package net.hn.hnms.biz.indicator.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import lombok.RequiredArgsConstructor;
import net.hn.hnms.biz.indicator.dao.SysIndicatorModelPercentMapper;
import net.hn.hnms.biz.indicator.entity.*;
import net.hn.hnms.biz.indicator.util.IndicatorUtil;
import net.hn.hnms.biz.indicator.util.PageUtil;
import net.hn.hnms.biz.indicator.util.ScoreLevel;
import net.hn.hnms.sys.common.core.utils.StringUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static net.hn.hnms.biz.indicator.entity.Constant.MINECODE_COMPANYNAME_MAP;
import static net.hn.hnms.biz.indicator.entity.Constant.MINECODE_NAME_MAP;

/**
 * @author 智呈物联 nzw
 * @date 2022/8/24
 */
@Service
@RequiredArgsConstructor
public class SysIndicatorModelService {

    private final JdbcTemplate locationJdbcTemplate;
    public static final String strDefault=null;

    SysIndicatorService sysIndicatorService;

    SysIndicatorModelPercentMapper sysIndicatorModelPercentMapper;


    @Autowired
    public void setSysIndicatorModelPercentMapper(SysIndicatorModelPercentMapper sysIndicatorModelPercentMapper) {
        this.sysIndicatorModelPercentMapper = sysIndicatorModelPercentMapper;
    }

    @Autowired
    public void setSysIndicatorService(SysIndicatorService sysIndicatorService) {
        this.sysIndicatorService = sysIndicatorService;
    }

    private static int lenthpart=2;

    public Map analyse(String type,String mineCode) throws Exception {
        Map result=new HashMap(3);
        Date date = new Date();
        List<GasModelValueDTO> modelList= new ArrayList<>();
        List<Map<String,String>> sumList = sysIndicatorModelPercentMapper.queryModelListV2(
                DateUtil.format(date,"yyyy-MM-dd")
                , IndicatorUtil.getGasCode()
                ,IndicatorUtil.getFireCode()
                ,IndicatorUtil.getDustCode()
                ,IndicatorUtil.getFloodCode()
                ,IndicatorUtil.getRoofCode()
                ,mineCode
        );
        Map<String,Object> re = new HashMap<>();
        Map<String,Object> re_second = new HashMap<>();
        if(sumList!=null){
            for(Map<String,String> map :sumList){
                if(map.get("totalSum")!=null) {
                    BigDecimal a = new BigDecimal(String.valueOf(map.get("totalSum")));
                    //四舍五入保留两位小数
                    re.put(map.get("indicatorFirstLevelName"),
                            a.divide(BigDecimal.valueOf(1), lenthpart, BigDecimal.ROUND_HALF_UP));
                    re_second.put(map.get("indicatorFirstLevelName"),
                            map.get("indicatorSecondLevelName"));
                }
            }
        }
        String sum = "";
        if(Objects.equals(type, Constant.GAS)){
            List<Map<String,Object>> list = sysIndicatorModelPercentMapper.queryGasModelListV2(
                    DateUtil.format(new Date(),"yyyy-MM-dd")
                    ,IndicatorUtil.getGasCode()
            );
            modelList = new ArrayList<>();
            for(Map<String,Object> map :list){
                modelList.add(JSON.parseObject(JSON.toJSONString(map),GasModelValueDTO.class));
            }
            sysIndicatorService.processWeight(modelList,IndicatorUtil.getGasCode());
            sum = MapUtils.getString(re,"瓦斯");
        }
        if(Objects.equals(type,Constant.FIRE)){
            List<Map<String,Object>> list = sysIndicatorModelPercentMapper.queryFireModelListV2(
                    DateUtil.format(new Date(),"yyyy-MM-dd"),IndicatorUtil.getFireCode()
            );
            modelList = new ArrayList<>();
            for(Map<String,Object> map :list){
                modelList.add(JSON.parseObject(JSON.toJSONString(map),GasModelValueDTO.class));
            }
            sysIndicatorService.processWeight(modelList,IndicatorUtil.getFireCode());
            //返回二级名称
            result.put("names",Arrays.asList("内因","外因","人员安全素质","火灾安全管理"));
            sum = MapUtils.getString(re,"火灾");
        }
        if(Objects.equals(type,Constant.WATER)){
            List<Map<String,Object>> list = sysIndicatorModelPercentMapper.queryFireModelListV2(
                    DateUtil.format(new Date(),"yyyy-MM-dd"),IndicatorUtil.getFloodCode()
            );
            modelList = new ArrayList<>();
            for(Map<String,Object> map :list){
                modelList.add(JSON.parseObject(JSON.toJSONString(map),GasModelValueDTO.class));
            }
            sum = MapUtils.getString(re,"水害");
        }
        if(Objects.equals(type,Constant.ROOF)){
            List<Map<String,Object>> list = sysIndicatorModelPercentMapper.queryFireModelListV2(
                    DateUtil.format(new Date(),"yyyy-MM-dd"),IndicatorUtil.getRoofCode()
            );
            modelList = new ArrayList<>();
            for(Map<String,Object> map :list){
                modelList.add(JSON.parseObject(JSON.toJSONString(map),GasModelValueDTO.class));
            }
            sum = MapUtils.getString(re,"顶板");
        }
        if(Objects.equals(type,Constant.INDICATOR_DUST)){
            List<Map<String,Object>> list = sysIndicatorModelPercentMapper.queryGasModelListV2(
                    DateUtil.formatDateTime(new Date())
                    ,IndicatorUtil.getDustCode()
            );
            modelList = new ArrayList<>();
            for(Map<String,Object> map :list){
                modelList.add(JSON.parseObject(JSON.toJSONString(map),GasModelValueDTO.class));
            }
            sysIndicatorService.processWeight(modelList,IndicatorUtil.getDustCode());
            sum = MapUtils.getString(re,"粉尘");
        }
        result.put("total",0);
        result.put("problem",0);
        result.put("sum",0);
        result.put("problemList",null);
        if(modelList!=null){
            result.put("total",modelList.size());
            List<GasModelValueDTO> problemGasModelList = modelList.stream().filter(s-> Double.valueOf(s.getProblemStr()) >0).collect(Collectors.toList());
//            //火灾处理三种指标 火灾暂不处理
//            if(Objects.equals(type,Constant.FIRE)){
//                result.put("total", 10);
//                if(CollectionUtil.isNotEmpty(problemGasModelList)){
//                    Date yestday=DateUtil.offsetDay(date,-1);
//                    Map<String, List<DwsFireComprehensiveEarlyAlarm>> collect = fireComprehensiveEarlyAlarmService.lambdaQuery()
//                            .between(DwsFireComprehensiveEarlyAlarm::getAlarmTime, DateUtil.beginOfDay(yestday), DateUtil.endOfDay(yestday))
//                            .list().stream()
//                            .collect(Collectors.groupingBy(DwsFireComprehensiveEarlyAlarm::getSensorType));
//                    problemGasModelList.stream()
//                            .filter(item->Objects.equals(item.getIndicatorThirdLevelCode(),"200301"))
//                            .forEach(item->{
//                                List<DwsFireComprehensiveEarlyAlarm> alarms = collect.get("0003");
//                                if(CollectionUtil.isNotEmpty(alarms)){
//                                    StringBuilder builder=new StringBuilder();
//                                    builder.append("累计报警");
//                                    builder.append(alarms.size() + "次。");
//                                    builder.append("其中，");
//                                    for(DwsFireComprehensiveEarlyAlarm alarm:alarms){
//                                        builder.append("报警地点为");
//                                        builder.append(ConstantMap.LOCATION_TYPE.get(alarm.getLocationType()));
//                                        builder.append(",");
//                                        builder.append("报警时长为");
//                                        builder.append(alarm.getAlarmDuration());
//                                        builder.append("分钟；");
//                                    }
////                                    item.setJudgeReason(item.getJudgeReason()+builder.toString());
//                                    item.setJudgeReason(builder.toString());
//                                }
//
//                            });
//                    problemGasModelList.stream()
//                            .filter(item->Objects.equals(item.getIndicatorThirdLevelCode(),"200303"))
//                            .forEach(item->{
//                                List<DwsFireComprehensiveEarlyAlarm> alarms = collect.get("1008");
//                                if(CollectionUtil.isNotEmpty(alarms)){
//                                    StringBuilder builder=new StringBuilder();
//                                    builder.append("累计报警");
//                                    builder.append(alarms.size() + "次。");
//                                    builder.append("其中，");
//                                    for(DwsFireComprehensiveEarlyAlarm alarm:alarms){
//                                        builder.append("报警地点为");
//                                        builder.append(ConstantMap.LOCATION_TYPE.get(alarm.getLocationType()));
//                                        builder.append(",");
//                                        builder.append("报警时长为");
//                                        builder.append(alarm.getAlarmDuration());
//                                        builder.append("分钟；");
//                                    }
////                                    item.setJudgeReason(item.getJudgeReason()+builder.toString());
//                                    item.setJudgeReason(builder.toString());
//                                }
//
//                            });
//                    problemGasModelList.stream()
//                            .filter(item->Objects.equals(item.getIndicatorThirdLevelCode(),"200302"))
//                            .forEach(item->{
//                                List<DwsFireComprehensiveEarlyAlarm> alarms =new ArrayList<>();
//                                collect.forEach((k,v)->{
//                                    if(!Objects.equals("0003",k)&&!Objects.equals("1008",k)){
//                                        alarms.addAll(v);
//                                    }
//                                });
//                                if(CollectionUtil.isNotEmpty(alarms)){
//                                    StringBuilder builder=new StringBuilder();
//                                    builder.append("累计报警");
//                                    builder.append(alarms.size() + "次。");
//                                    builder.append("其中，");
//                                    for(DwsFireComprehensiveEarlyAlarm alarm:alarms){
//                                        builder.append("报警地点为");
//                                        builder.append(ConstantMap.LOCATION_TYPE.get(alarm.getLocationType()));
//                                        builder.append(",");
//                                        builder.append("报警时长为");
//                                        builder.append(alarm.getAlarmDuration());
//                                        builder.append("分钟；");
//                                    }
////                                    item.setJudgeReason(item.getJudgeReason()+builder.toString());
//                                    item.setJudgeReason(builder.toString());
//                                }
//
//                            });
//                }
//            }
            result.put("problem",problemGasModelList.size());
            result.put("sum",sum);
            result.put("problemList",problemGasModelList);
        }
        return result;
    }

    public Map<String, Object> queryModelList(String mineCode) {
        return queryModelList(new Date(),mineCode);
    }

    public Map<String, Object> queryModelList(Date date,String mineCode) {
        List<IndicatorModelValueVO> content = new ArrayList<>();
        IndicatorModelValueVO indicatorModelValueVO = getModelList(date,mineCode);
        content.add(indicatorModelValueVO);
        return PageUtil.toPage(content, content.size());
    }

    public IndicatorModelValueVO getModelList(Date date,String mineCode) {
        List<ModelListDTO> maps = queryModelListV2(date,mineCode);
        return doGetTotal(maps);
    }

    public List<ModelListDTO> queryModelListV2(Date date,String mineCode){
        List<ModelListDTO> modelListDTOS = new ArrayList<>();
        List<Map<String,String>> mapList = sysIndicatorModelPercentMapper.queryModelListV2(DateUtil.format(date,"yyyy-MM-dd")
                ,IndicatorUtil.getGasCode()
                ,IndicatorUtil.getFireCode()
                ,IndicatorUtil.getDustCode()
                ,IndicatorUtil.getFloodCode()
                ,IndicatorUtil.getRoofCode()
                ,mineCode);
        for (Map<String,String> map:mapList){
            modelListDTOS.add(JSON.parseObject(JSON.toJSONString(map),ModelListDTO.class));
        }
        return modelListDTOS;
    }

    private IndicatorModelValueVO doGetTotal(List<ModelListDTO> maps){
        IndicatorModelValueVO indicatorModelValueVO = new IndicatorModelValueVO();
        //总分
        maps.forEach(item -> {
            String name = item.getIndicatorFirstLevelName();
            if(item.getTotalSum()==null){
                item.setTotalSum("0");
            }
            double indicatorModelValue = Double.valueOf(item.getTotalSum());
            BigDecimal indicatorValue = BigDecimal.valueOf(indicatorModelValue).setScale(lenthpart, BigDecimal.ROUND_HALF_UP);
            if(Objects.equals(name,"水害")){
                indicatorModelValueVO.setTotal(
                        NumberUtil.add(indicatorModelValueVO.getTotal(), NumberUtil.mul(indicatorModelValue, Constant.WATER_WEIGHT))
                                .setScale(lenthpart, BigDecimal.ROUND_HALF_UP));
                indicatorModelValueVO.setWater(indicatorValue);
            }
            if(Objects.equals(name,"瓦斯")){
                indicatorModelValueVO.setTotal(
                        NumberUtil.add(indicatorModelValueVO.getTotal(), NumberUtil.mul(indicatorModelValue, Constant.GAS_WEIGHT))
                                .setScale(lenthpart, BigDecimal.ROUND_HALF_UP));
                indicatorModelValueVO.setGas(indicatorValue);
            }
            if(Objects.equals(name,"粉尘")){
                indicatorModelValueVO.setTotal(
                        NumberUtil.add(indicatorModelValueVO.getTotal(), NumberUtil.mul(indicatorModelValue, Constant.DUST_WEIGHT))
                                .setScale(lenthpart, BigDecimal.ROUND_HALF_UP));
                indicatorModelValueVO.setDust(indicatorValue);
            }
            if(Objects.equals(name,"火灾")){
                indicatorModelValueVO.setTotal(
                        NumberUtil.add(indicatorModelValueVO.getTotal(), NumberUtil.mul(indicatorModelValue, Constant.FIRE_WEIGHT))
                                .setScale(lenthpart, BigDecimal.ROUND_HALF_UP));
                indicatorModelValueVO.setFire(indicatorValue);
            }
            if(Objects.equals(name,"顶板")){
                indicatorModelValueVO.setTotal(
                        NumberUtil.add(indicatorModelValueVO.getTotal(), NumberUtil.mul(indicatorModelValue, Constant.ABSCISS_WEIGHT))
                                .setScale(lenthpart, BigDecimal.ROUND_HALF_UP));
                indicatorModelValueVO.setAbsciss(indicatorValue);
            }
        });
        if (indicatorModelValueVO.getTotal().compareTo(new BigDecimal("0"))>0){
            indicatorModelValueVO.setTotal(indicatorModelValueVO.getTotal().add(new BigDecimal("15.00")));
        }
        Integer total = Double.valueOf(indicatorModelValueVO.getTotal().toString()).intValue();
        indicatorModelValueVO.setAssess(IndicatorUtil.levelName(Double.valueOf(total)));
        return indicatorModelValueVO;
    }

    public Map<String, Object> queryModelListCompare(String mineCode) throws Exception {
        List<ModelListDTO> maps = queryModelListV2(new Date(),mineCode);//当天数据
        List<ModelListDTO> maps_before = queryModelListV2(DateUtil.offsetDay(new Date(),-1),mineCode);//前一天数据
        Map<String,Object> re = new HashMap<>();
        Map<String,Object> re_before = new HashMap<>();
        if(maps_before!=null && maps_before.size()>0){//前一天数据
            maps_before.forEach(str ->{
                String totalSum = str.getTotalSum();
                if(StrUtil.isBlank(totalSum)){
                    totalSum="0";
                }
                BigDecimal a = new BigDecimal(totalSum);
                re_before.put(str.getIndicatorFirstLevelName(),a.divide(BigDecimal.valueOf(1),lenthpart,BigDecimal.ROUND_HALF_UP));
            });
        }
        if(maps!=null && maps.size()>0){//今天数据
            maps.forEach(str ->{
                String totalSum = str.getTotalSum();
                if(StrUtil.isBlank(totalSum)){
                    totalSum="0";
                }
                BigDecimal a = new BigDecimal(totalSum);
                //四舍五入保留两位小数
                ModelListVO modelListVO=new ModelListVO();
                modelListVO.setTodayTotalSum(a.divide(BigDecimal.valueOf(1),lenthpart,BigDecimal.ROUND_HALF_UP).doubleValue());
                modelListVO.setYesterdayTotalSum(MapUtils.getDouble(re_before,str.getIndicatorFirstLevelName()));
                re.put(getValueByLabel(str.getIndicatorFirstLevelName()),modelListVO);
            });
        }

        checkModel(re);
        re.putAll(doAppraise(mineCode));
        return re;
    }

    public List<CompanyScoreVO> calculateTotalScore() {
        List<CompanyScoreVO> result = new ArrayList<>();
        Map<String, List<ModelListDTO>> indicatorsByMine = new HashMap<>();
//        Date date = new Date();

        List<Map<String, Object>> mapList = sysIndicatorModelPercentMapper.queryCompanyModelListV2(
                IndicatorUtil.getGasCode()
                ,IndicatorUtil.getFireCode()
                ,IndicatorUtil.getDustCode()
                ,IndicatorUtil.getFloodCode()
                ,IndicatorUtil.getRoofCode());
        // 按煤矿分开
        mapList.forEach(m -> {
            if(indicatorsByMine.containsKey(m.get("mine_code"))) {
                indicatorsByMine.get(m.get("mine_code")).add(
                        new ModelListDTO(((BigDecimal) m.get("totalSum")).toPlainString(),
                                (String) m.get("indicatorFirstLevelName"),
                                (String) m.get("indicatorSecondLevelName")));
            } else {
                List<ModelListDTO> modelListDTOS = new ArrayList<>();
                modelListDTOS.add(new ModelListDTO(((BigDecimal) m.get("totalSum")).toPlainString(),
                        (String) m.get("indicatorFirstLevelName"),
                        (String) m.get("indicatorSecondLevelName")));
                indicatorsByMine.put(
                        (String) m.get("mine_code"), modelListDTOS);
            }
        });

        indicatorsByMine.forEach((s, dto) -> {
            CompanyScoreVO companyScoreVO = new CompanyScoreVO();
            companyScoreVO.setMineCode(s);
            companyScoreVO.setComprehensive(doGetTotal(dto).getTotal());
            companyScoreVO.setMineName(MINECODE_NAME_MAP.get(s));
            companyScoreVO.setCompanyName(MINECODE_COMPANYNAME_MAP.get(s));
            result.add(companyScoreVO);
        });
        return result;
    }

    private String getValueByLabel(String name){
        if(Objects.equals(name,"水害")){
            return "water";
        }
        if(Objects.equals(name,"瓦斯")){
            return "gas";
        }
        if(Objects.equals(name,"火灾")){
            return "fire";
        }
        if(Objects.equals(name,"顶板")){
            return "absciss";
        }
        if(Objects.equals(name,"粉尘")){
            return "dust";
        }
        return null;
    }

    private void checkModel(Map<String,Object> re){
        Map map=new HashMap(){{put("todayTotalSum",null);put("yesterdayTotalSum",null);}};
        if(re.get("water")==null){
            re.put("water",map);
        }
        if(re.get("gas")==null){
            re.put("gas",map);
        }
        if(re.get("fire")==null){
            re.put("fire",map);
        }
        if(re.get("absciss")==null){
            re.put("absciss",map);
        }
        if(re.get("dust")==null){
            re.put("dust",map);
        }
    }

    private Map doAppraise(String mineCode) throws Exception {
        Map<String, Object> fire = analyse(Constant.FIRE,mineCode);
        Map<String, Object> gas = analyse(Constant.GAS,mineCode);
        Map<String, Object> water = analyse(Constant.WATER,mineCode);
        Map<String, Object> roof = analyse(Constant.ROOF,mineCode);
        Map<String, Object> dust = analyse(Constant.INDICATOR_DUST,mineCode);

        List<GasModelValueDTO> problemList = new ArrayList<>();
        problemList.addAll((List<GasModelValueDTO>)fire.get("problemList"));
        problemList.addAll((List<GasModelValueDTO>)gas.get("problemList"));
        problemList.addAll((List<GasModelValueDTO>)water.get("problemList"));
        problemList.addAll((List<GasModelValueDTO>)roof.get("problemList"));
        problemList.addAll((List<GasModelValueDTO>)dust.get("problemList"));

        Map problemMap = new HashMap();
        problemMap.put("fire",(List<GasModelValueDTO>)fire.get("problemList"));
        problemMap.put("gas",(List<GasModelValueDTO>)gas.get("problemList"));
        problemMap.put("water",(List<GasModelValueDTO>)water.get("problemList"));
        problemMap.put("roof",(List<GasModelValueDTO>)roof.get("problemList"));
        problemMap.put("dust",(List<GasModelValueDTO>)dust.get("problemList"));

        RiskLevelNum riskLevelNum = new RiskLevelNum();
        problemList.forEach(map -> {
            switch(ScoreLevel.getLevel(new BigDecimal(map.getProblemStr()))) {
                case 1:
                    riskLevelNum.setHighNum(riskLevelNum.getHighNum() + 1);
                    break;
                case 2:
                    riskLevelNum.setHighNum(riskLevelNum.getHighNum() + 1);
                    break;
                case 3:
                    riskLevelNum.setHigherNum(riskLevelNum.getHigherNum() + 1);
                    break;
                case 4:
                    riskLevelNum.setGeneralNum(riskLevelNum.getGeneralNum() + 1);
                    break;
                default:
                    break;
            }
        });
        IndicatorModelValueVO indicatorModelValueVO = getModelList(mineCode);
        Double score = Double.valueOf(indicatorModelValueVO.getTotal().toString());
        String riskLevel = ScoreLevel.getRiskLevelString(score);
        String now = DateUtil.format(new Date(), "yyyy年M月d日");
        String message = String.format("根据煤矿综合风险分析结果可知，该矿 %s，" +
                        "整体风险得分为: %.2f分，属于%s风险。" +
                        "其中扣分项 %d项，发生事故的可能性：%s。", now, score,
                riskLevel, riskLevelNum.getVeryHighNum() +
                        riskLevelNum.getHighNum() + riskLevelNum.getHigherNum() +
                        riskLevelNum.getGeneralNum(), riskLevel);
        //导出综合分析tmpType=3
        String url = IndicatorUtil.getUrl()+"api/template/exportTmp?tmpType=3";
        return new HashMap(){{
            put("appraise", message);
            put("reportUrl", url);
            put("time", now);
            put("problemList",problemMap);
        }};
    }

    public IndicatorModelValueVO getModelList(String mineCode) {
        return getModelList(new Date(),mineCode);
    }

    public Map<String,Object> save(SysIndicatorModel sysIndicatorModel){
        String indicatorFirstLevelCode = sysIndicatorModel.getIndicatorFirstLevelCode();
        String indicatorSecondLevelCode = sysIndicatorModel.getIndicatorSecondLevelCode();
        String indicatorThirdLevelCode = sysIndicatorModel.getIndicatorThirdLevelCode();
        String indicatorValue = sysIndicatorModel.getIndicatorValue();
        String originalValue = sysIndicatorModel.getOriginalValue();
        Date modelTime = new Date();
        Date dataTime = sysIndicatorModel.getDataTime();
        return sysIndicatorModelPercentMapper.saveModel(modelTime,dataTime,indicatorFirstLevelCode,indicatorSecondLevelCode,indicatorThirdLevelCode,indicatorValue,originalValue);
    }

    public boolean saveDto(SysIndicatorModelDto entity) {

        List<Map<String,Object>> history=selectHistory(entity.getIndicatorSecondLevelCode(),entity.getIndicatorFirstLevelCode());
        if (history.size()==0){
            entity.setModelTime(new Date());
        }else {
            entity.setModelTime((Date) history.get(0).get("model_time"));
        }
        saveBatch(history,entity);
        return true;
    }

    public boolean remove(String indicatorSecondLevelCode,String indicatorFirstLevelCode) {
        List<Map<String,Object>> historys=selectHistory(indicatorSecondLevelCode, indicatorFirstLevelCode);
        return historys.size()==0?false:saveBatch(historys,null);
    }

    private List<Map<String,Object>> selectHistory(String indicatorSecondLevelCode, String indicatorFirstLevelCode){
        StringBuffer sql = new StringBuffer("SELECT\n" +
                "\tindicator_first_level_code,\n" +
                "\tindicator_second_level_code,\n" +
                "\tindicator_value,\n" +
                "\tnow( ) AS model_time,\n" +
                "\tdata_time \n" +
                "FROM\n" +
                "\tssys_indicator_model \n" +
                "WHERE\n" +
                "\tmodel_time = ( SELECT MAX ( model_time ) FROM ssys_indicator_model )");
        if (indicatorSecondLevelCode!=null){
            sql.append("AND indicator_second_level_code != '"+indicatorSecondLevelCode+"'");
        }
        if (indicatorFirstLevelCode!=null){
            sql.append("AND indicator_first_level_code != '"+indicatorFirstLevelCode+"'");
        }
        return locationJdbcTemplate.queryForList(sql.toString());
    }

    private boolean saveBatch(List<Map<String,Object>> history,SysIndicatorModelDto entity){
        StringBuffer sqls = new StringBuffer("INSERT INTO ssys_indicator_model ( indicator_first_level_code, indicator_second_level_code, indicator_value, model_time, data_time )\n" +
                "VALUES");
        for(Map<String,Object> map:history){
            sqls.append("('"+map.get("indicatorFirstLevelCode")+"',");
            sqls.append("'"+map.get("indicatorSecondLevelCode")+"',");
            sqls.append("'"+map.get("indicatorValue")+"',");
            sqls.append("'"+map.get("modelTime")+"',");
            sqls.append("'"+map.get("dataTime")+"')");
        }
        if (entity!=null) {
            sqls.append("('" + entity.getIndicatorFirstLevelCode() + "',");
            sqls.append("'" + entity.getIndicatorSecondLevelCode() + "',");
            sqls.append("'" + entity.getIndicatorValue() + "',");
            sqls.append("'" + DateUtil.format(entity.getModelTime(), "yyyy-MM-dd HH:mm:ss") + "',");
            sqls.append("'" + DateUtil.format(entity.getDataTime(), "yyyy-MM-dd HH:mm:ss") + "')");
        }
        locationJdbcTemplate.execute(sqls.toString());
        return true;
    }

    //风险预测----7天或30天内总分曲线
    public Map<String,Object> curve(String type){
        //获取起始时间
        Calendar calendar = Calendar.getInstance();
        Date nowDate = new Date();
        calendar.setTime(nowDate);
        try {
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - Integer.parseInt(type));
        }catch (Exception e){
            calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - 30);
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String beginTime = simpleDateFormat.format(calendar.getTime());
        String endTime = simpleDateFormat.format(nowDate);

        List<Map<String, Object> > floodResult = new ArrayList<>();
        List<Map<String, Object> > fireResult = new ArrayList<>();
        List<Map<String, Object> > gasResult = new ArrayList<>();
        List<Map<String, Object> > dustResult = new ArrayList<>();
        List<Map<String, Object> > roofResult = new ArrayList<>();

        floodResult = sysIndicatorModelPercentMapper.queryGasModelListByDateV2(IndicatorUtil.getFloodCode(),beginTime,endTime);
        fireResult = sysIndicatorModelPercentMapper.queryGasModelListByDateV2(IndicatorUtil.getFireCode(),beginTime,endTime);
        gasResult = sysIndicatorModelPercentMapper.queryGasModelListByDateV2(IndicatorUtil.getGasCode(),beginTime,endTime);
        dustResult = sysIndicatorModelPercentMapper.queryGasModelListByDateV2(IndicatorUtil.getDustCode(),beginTime,endTime);
        roofResult = sysIndicatorModelPercentMapper.queryGasModelListByDateV2(IndicatorUtil.getRoofCode(),beginTime,endTime);

        Map<String,Object> floodResultMap = curveListToMap(floodResult);
        Map<String,Object> fireResultMap = curveListToMap(fireResult);
        Map<String,Object> gasResultMap = curveListToMap(gasResult);
        Map<String,Object> dustResultMap = curveListToMap(dustResult);
        Map<String,Object> roofResultMap = curveListToMap(roofResult);

        List<String> yList = new ArrayList<>();
        List<BigDecimal> floodList = new ArrayList<>();
        List<BigDecimal> fireList = new ArrayList<>();
        List<BigDecimal> gasList = new ArrayList<>();
        List<BigDecimal> dustList = new ArrayList<>();
        List<BigDecimal> roofList = new ArrayList<>();
        //综合得分列表
        List<BigDecimal> overallRatingsList = new ArrayList<>();

        for(int i=0;i<35;i++){
            if (i!=0){
                calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);
            }
            //横坐标赋值
            String yDate = simpleDateFormat.format(calendar.getTime());
            yList.add(yDate);

            BigDecimal flood = new BigDecimal(floodResultMap.get(yDate)==null?"0.00":floodResultMap.get(yDate)+"");
            BigDecimal fire = new BigDecimal(fireResultMap.get(yDate)==null?"0.00":fireResultMap.get(yDate)+"");
            BigDecimal gas = new BigDecimal(gasResultMap.get(yDate)==null?"0.00":gasResultMap.get(yDate)+"");
            BigDecimal dust = new BigDecimal(dustResultMap.get(yDate)==null?"0.00":dustResultMap.get(yDate)+"");
            BigDecimal roof = new BigDecimal(roofResultMap.get(yDate)==null?"0.00":roofResultMap.get(yDate)+"");

            floodList.add(flood);
            fireList.add(fire);
            gasList.add(gas);
            dustList.add(dust);
            roofList.add(roof);

            //计算总分
            BigDecimal overallRatings = flood.multiply(new BigDecimal(Double.toString(Constant.WATER_WEIGHT)));
            overallRatings = overallRatings.add(fire.multiply(new BigDecimal(Double.toString(Constant.FIRE_WEIGHT))));
            overallRatings = overallRatings.add(gas.multiply(new BigDecimal(Double.toString(Constant.GAS_WEIGHT))));
            overallRatings = overallRatings.add(dust.multiply(new BigDecimal(Double.toString(Constant.DUST_WEIGHT))));

            //顶板分数暂定为100
            if (overallRatings.compareTo(new BigDecimal("0.00"))>0){
                overallRatings = overallRatings.add(new BigDecimal("100.00").multiply(new BigDecimal(Double.toString(Constant.ABSCISS_WEIGHT))));
            }
            overallRatings = overallRatings.setScale(2, RoundingMode.HALF_UP);
            overallRatingsList.add(overallRatings);

            if (endTime.equals(yDate)){
                break;
            }
        }

        BigDecimal sum = new BigDecimal("0.00");
        //计算预期值
        for (BigDecimal overallRatings:overallRatingsList){
            sum = sum.add(overallRatings);
        }

        BigDecimal average = sum.divide(new BigDecimal(overallRatingsList.size()+""),BigDecimal.ROUND_CEILING);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) + 1);
        yList.add(simpleDateFormat.format(calendar.getTime()));
        overallRatingsList.add(average);


        Map<String,Object> curveMap = new HashMap<>();
        curveMap.put("values",overallRatingsList);

        curveMap.put("flood",floodList);
        curveMap.put("fire",fireList);
        curveMap.put("gas",gasList);
        curveMap.put("dust",dustList);
        curveMap.put("roof",roofList);

        curveMap.put("yList",yList);
        return curveMap;
    }

    private Map<String,Object> curveListToMap(List<Map<String, Object>> data){
        Map<String,Object> result = new HashMap<>();
        if (data!=null){
            for(Map<String, Object> map:data){
                result.put(map.get("dataStr")+"",map.get("totalVal"));
            }
        }
        return result;
    }


    public Map curve1(String type, Date startTime,Date endTime,boolean future){
        if(Objects.isNull(startTime)){
            endTime=new Date();
            startTime=DateUtil.offsetDay(endTime,-7);
        }
        long day = DateUtil.betweenDay(startTime, endTime,true);
        List days = getDays(startTime, day);
        Map result=new HashMap(2);
        result.put("days",days);
        String begin = new SimpleDateFormat("YYYY-MM-dd").format(startTime);
        String end = new SimpleDateFormat("YYYY-MM-dd").format(endTime);
        List<Map<String, Object> > result_val = new ArrayList<>();
        boolean allFlag=true;
        Map param=new HashMap(){{
            put("beginDate",begin);put("endDate",end);
        }};
        if(Objects.equals(type, Constant.GAS)){
            param.put("code",IndicatorUtil.getGasCode());
            result_val= sysIndicatorModelPercentMapper.queryGasModelListByDateV2(IndicatorUtil.getGasCode(),begin,end);
            allFlag = false;
        }
        if(Objects.equals(type,Constant.FIRE)){
            param.put("code",IndicatorUtil.getFireCode());
            result_val=sysIndicatorModelPercentMapper.queryFireModelListByDateV2(IndicatorUtil.getFireCode(),begin,end);
            allFlag = false;
        }
        if(Objects.equals(type,Constant.WATER)){
            result_val=sysIndicatorModelPercentMapper.queryFireModelListByDateV2(IndicatorUtil.getFloodCode(),begin,end);
            allFlag = false;
        }
        if(Objects.equals(type,Constant.ROOF)){
            result_val=sysIndicatorModelPercentMapper.queryFireModelListByDateV2(IndicatorUtil.getRoofCode(),begin,end);
            allFlag = false;
        }
        if (Objects.equals(type, Constant.INDICATOR_DUST)) {
            result_val = sysIndicatorModelPercentMapper.queryDustModelListByDateV2(IndicatorUtil.getDustCode(),begin,end);
            allFlag = false;
        }
        if(allFlag){
            List<String> strings = processAll(begin, end, days);
            result.put("values",strings);
            if(future){
                //加一天 取前7天的平均值
                doFuture(days,strings);
            }
            return result;
        }
        Map<String,Object> re = new HashMap<>();
        if(result_val!=null){
            for(Map<String, Object> map :result_val){
                re.put(MapUtils.getString(map,"dataStr"),MapUtils.getString(map,"totalVal"));
            }
        }
        List<String> value = new ArrayList<>();
        for(Object str:days){
            String s = (String)str;
            value.add(MapUtils.getString(re,s)==null?strDefault:MapUtils.getString(re,s));
        }
        result.put("values",value);
        return result;
    }

    private List getDays(Date startTime,Long day){
        List<String> days=new ArrayList<>();
        for (int i = 0; i <= day.intValue(); i++) {
            String format = DateUtil.format(DateUtil.offsetDay(startTime, i), DatePattern.NORM_DATE_FORMAT);
            days.add(format);
        }
        return days;
    }

    private List<String> processAll(String begin,String end,List days){
        List<String> value=new ArrayList<>();
        Map param=new HashMap(){{
            put("beginDate",begin);put("endDate",end);
            put("code", IndicatorUtil.getGasCode());
        }};
        List<Map<String, Object> > result_val1= sysIndicatorModelPercentMapper.queryGasModelListByDateV2(IndicatorUtil.getGasCode(),begin,end);
        param.put("code",IndicatorUtil.getFireCode());
        List<Map<String, Object> > result_val2=sysIndicatorModelPercentMapper.queryFireModelListByDateV2(IndicatorUtil.getFireCode(),begin,end);
//        List<Map<String, Object> > result_val3=sysIndicatorModelPercentMapper.queryFloodModelListByDate(begin,end);
//        List<Map<String, Object> > result_val4=sysIndicatorModelPercentMapper.queryRoofModelListByDate(begin,end);
        List<Map<String, Object> > result_val5=sysIndicatorModelPercentMapper.queryDustModelListByDateV2(IndicatorUtil.getDustCode(),begin,end);


        for(Object str:days){
            final BigDecimal[] total = {new BigDecimal(0)};
            result_val1.forEach(item->{
                if(Objects.equals(str,MapUtils.getString(item,"dataStr"))){
                    String val = MapUtils.getString(item, "totalVal");
                    if(StrUtil.isBlank(val)){
                        val="0";
                    }
                    total[0] =NumberUtil.add(total[0], NumberUtil.mul(new BigDecimal(val), Constant.GAS_WEIGHT))
                            .setScale(0, BigDecimal.ROUND_HALF_UP);
                }
            });
            result_val2.forEach(item->{
                if(Objects.equals(str,MapUtils.getString(item,"dataStr"))){
                    String val = MapUtils.getString(item, "totalVal");
                    if(StrUtil.isBlank(val)){
                        val="0";
                    }
                    total[0] =NumberUtil.add(total[0], NumberUtil.mul(new BigDecimal(val), Constant.FIRE_WEIGHT))
                            .setScale(0, BigDecimal.ROUND_HALF_UP);
                }
            });
//            result_val3.forEach(item->{
//                if(Objects.equals(str,MapUtils.getString(item,"dataStr"))){
//                    String val = MapUtils.getString(item, "totalVal");
//                    if(StrUtil.isBlank(val)){
//                        val="0";
//                    }
//                    total[0] =NumberUtil.add(total[0], NumberUtil.mul(new BigDecimal(val), Constant.WATER_WEIGHT))
//                            .setScale(0, BigDecimal.ROUND_HALF_UP);
//                }
//            });
//            result_val4.forEach(item->{
//                if(Objects.equals(str,MapUtils.getString(item,"dataStr"))){
//                    String val = MapUtils.getString(item, "totalVal");
//                    if(StrUtil.isBlank(val)){
//                        val="0";
//                    }
//                    total[0] =NumberUtil.add(total[0], NumberUtil.mul(new BigDecimal(val), Constant.ABSCISS_WEIGHT))
//                            .setScale(0, BigDecimal.ROUND_HALF_UP);
//                }
//            });
            result_val5.forEach(item->{
                if(Objects.equals(str,MapUtils.getString(item,"dataStr"))){
                    String val = MapUtils.getString(item, "totalVal");
                    if(StringUtils.isEmpty(val) || "0".equals(val)) {
                        val = "100";
                    }
                    total[0] =NumberUtil.add(total[0], NumberUtil.mul(new BigDecimal(val), Constant.DUST_WEIGHT))
                            .setScale(0, BigDecimal.ROUND_HALF_UP);
                }
            });
            value.add(total[0]+"");
        }
        return value;
    }

    private void doFuture(List<String> days,List<String> values){
        if(days.size()<7){
            return;
        }
        String lastDay = days.get(days.size() - 1);
        DateTime time = DateUtil.offsetDay(DateUtil.parse(lastDay, DatePattern.NORM_DATE_FORMAT).toJdkDate(), 1);
        String format = DateUtil.format(time, DatePattern.NORM_DATE_FORMAT);
        days.add(format);
        OptionalDouble average = values.subList(values.size() - 7, values.size()).stream().mapToDouble(Double::parseDouble).average();
        values.add(NumberUtil.roundStr(average.getAsDouble(),lenthpart));
    }

//    public Map<String, Object> pageList(String name, Pageable pageable) {
//        Page pages=new Page<>(pageable.getPageNumber(), pageable.getPageSize());
//        IPage<SysIndicatorModel> indicatorIPage=sysIndicatorModelPercentMapper.pageList(name,pages);
//        return PageUtil.toPage(indicatorIPage.getRecords(),indicatorIPage.getTotal());
//    }

    //获取指标模型分级数据
    public Map<String, Object> treeList(String name) {
        List<SysIndicator> list =  sysIndicatorService.list();
//        List<SysIndicator> indicators = list.stream().filter(item -> StringUtils.isBlank(item.getIndicatorSecondLevelCode()))
//                .collect(Collectors.toList());
        List<SysIndicator> indicators = new ArrayList<>();
        addFirst(list,indicators);

        Map<String, List<SysIndicator>> listTwoMap = list.stream().filter(item -> StringUtils.isNotBlank(item.getIndicatorSecondLevelCode())
                &&StringUtils.isBlank(item.getIndicatorThirdLevelCode()))
                .collect(Collectors.groupingBy(SysIndicator::getIndicatorFirstLevelCode));
        Map<String, List<SysIndicator>> listThirdMap = list.stream().filter(item -> StringUtils.isNotBlank(item.getIndicatorSecondLevelCode())
                &&StringUtils.isNotBlank(item.getIndicatorThirdLevelCode()))
                .peek(item->{
                    item.setIndicatorSecondLevelName(item.getIndicatorThirdLevelName());
                    item.setLevel(3);
                    item.setRoles(sysIndicatorService.rolesByIndicatorId(item.getId()));
                    item.setUniqueKey(item.getIndicatorSecondLevelCode()+item.getIndicatorThirdLevelCode()+item.getIndicatorThirdLevelCode());
                })
                .collect(Collectors.groupingBy(SysIndicator::getIndicatorSecondLevelCode));
        indicators.forEach(item->{
            item.setIndicatorSecondLevelName(item.getIndicatorFirstLevelName());
            List<SysIndicator> sysIndicators = listTwoMap.get(item.getIndicatorFirstLevelCode());
            if(CollectionUtil.isNotEmpty(sysIndicators)){
                sysIndicators.forEach(second->{
                    second.setChildren(listThirdMap.get(second.getIndicatorSecondLevelCode()));
                    second.setLevel(2);
                    second.setUniqueKey(item.getIndicatorFirstLevelCode()+second.getIndicatorSecondLevelCode());
                });
            }
            item.setChildren(sysIndicators);
            item.setLevel(1);
        });
        treeMatch(indicators,name);
        return PageUtil.toPage(indicators,indicators.size());
    }

    //获取指标模型分级数据-工具类
    private void addFirst(List<SysIndicator> listAll ,List<SysIndicator> indicatorsFirst ){
        Map<String, SysIndicator> indicatorMap = listAll.stream()
                .collect(Collectors.groupingBy(
                        SysIndicator::getIndicatorFirstLevelCode, Collectors.collectingAndThen(
                                Collectors.toList(), value -> value.get(0)
                        )
                ));
        indicatorMap.forEach((k,v)->{
            SysIndicator sysIndicator=new SysIndicator();sysIndicator.setIndicatorFirstLevelName(v.getIndicatorFirstLevelName());
            sysIndicator.setIndicatorFirstLevelCode(v.getIndicatorFirstLevelCode());
            sysIndicator.setId(v.getId());
            sysIndicator.setUniqueKey(v.getIndicatorFirstLevelCode());
            indicatorsFirst.add(sysIndicator);
        });
        indicatorsFirst.sort(Comparator.comparing(SysIndicator::getIndicatorFirstLevelCode));
    }

    //获取指标模型分级数据-工具类
    public static void treeMatch(List<SysIndicator> oneCategoryList,String keyword){
        if(StrUtil.isBlank(keyword)){
            return;
        }
        Iterator<SysIndicator> oneIter = oneCategoryList.iterator();
        while (oneIter.hasNext()){
            SysIndicator oneCategory = oneIter.next();
            // 如果包含则什么也不做（不移除），否则就看二级目录
            if(!oneCategory.getIndicatorSecondLevelName().contains(keyword)){
                List<SysIndicator> twoCategoryList = oneCategory.getChildren();
                if(CollectionUtil.isEmpty(twoCategoryList)){
                    continue;
                }
                Iterator<SysIndicator> twoIter = twoCategoryList.iterator();
                while (twoIter.hasNext()){
                    SysIndicator twoCategory = twoIter.next();
                    // 如果包含则什么也不做（不移除），否则就看三级目录
                    if(!twoCategory.getIndicatorSecondLevelName().contains(keyword)){
                        List<SysIndicator> threeCategoryList = twoCategory.getChildren();
                        if(CollectionUtil.isEmpty(threeCategoryList)){
                            continue;
                        }
                        Iterator<SysIndicator> threeIter = threeCategoryList.iterator();
                        while (threeIter.hasNext()){
                            SysIndicator threeCategory = threeIter.next();
                            if(!threeCategory.getIndicatorSecondLevelName().contains(keyword)){
                                threeIter.remove();
                            }
                        }
                        // 三级目录看完了，如果三级目录全部被移除，则移除二级目录
                        if(CollectionUtil.isEmpty(twoCategory.getChildren())){
                            twoIter.remove();
                        }
                    }
                }
                // 二级目录看完了，如果二级目录全部被移除，则移除一级目录
                if(CollectionUtil.isEmpty(oneCategory.getChildren())){
                    oneIter.remove();
                }
            }
        }
    }

    public ScoreParentVO getScore(String type){
        if (type==null||"".equals(type)){
            type = "7";
        }
        List<String> scoreType = new ArrayList<>(6);
        scoreType.add(IndicatorUtil.getGasCode());
        scoreType.add(IndicatorUtil.getFireCode());
        scoreType.add(IndicatorUtil.getDustCode());
        scoreType.add(IndicatorUtil.getFloodCode());
        scoreType.add(IndicatorUtil.getRoofCode());

        ScoreVO max = new ScoreVO();
        ScoreVO min = new ScoreVO();
        ScoreVO average = new ScoreVO();

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_YEAR,(0-Integer.parseInt(type)));

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        String dataTime = simpleDateFormat.format(calendar.getTime());
        scoreType.forEach(s->{
            Map<String,Object> scoreMap = sysIndicatorModelPercentMapper.getScore(dataTime,s);
            if (s==IndicatorUtil.getGasCode()){
                max.setGas(scoreMap.get("big")+"");
                min.setGas(scoreMap.get("small")+"");
                average.setGas(scoreMap.get("average")+"");
            }
            if (s==IndicatorUtil.getFireCode()){
                max.setFire(scoreMap.get("big")+"");
                min.setFire(scoreMap.get("small")+"");
                average.setFire(scoreMap.get("average")+"");
            }
            if (s==IndicatorUtil.getDustCode()){
                max.setDust(scoreMap.get("big")+"");
                min.setDust(scoreMap.get("small")+"");
                average.setDust(scoreMap.get("average")+"");
            }
            if (s==IndicatorUtil.getFloodCode()){
                max.setRockBurst(scoreMap.get("big")+"");
                min.setRockBurst(scoreMap.get("small")+"");
                average.setRockBurst(scoreMap.get("average")+"");
            }
            if (s==IndicatorUtil.getRoofCode()){
                max.setRoof(scoreMap.get("big")+"");
                min.setRoof(scoreMap.get("small")+"");
                average.setRoof(scoreMap.get("average")+"");
            }
        });

        ScoreParentVO scoreParentVO = new ScoreParentVO();
        scoreParentVO.setMax(max);
        scoreParentVO.setMin(min);
        scoreParentVO.setAverage(average);
        return scoreParentVO;
    }
}
